<?php

核心组件
    docker client
    docker deamon
    image：镜像文件只读，用于来container
    repository
        公共镜像
        私有仓库
    docker container：docker的运行实例，容器是一个隔离环境

    另外两个重要组件
    docker link：
    docker volume：

    yum -y install docker

    systemctl start docker.service
    ss -tunl
    docker images 列出docker使用的映像文件
    docker search <name>
    docker search busybox
    docker pull busybox
    docker pull hub.magedu.com:5000/busybox    // 私有地址 支持 ssl 
    docker images  // 列出镜像文件
    docker help run // 运行帮助
    docker run -it busybox:latest /bin/sh  // latest 标签  交互式运行shell
        i 打开一个终端交互式运行
        t  虚拟终端
    docker ps    // 列出正在运行的程序
    docker help commit 
    docker pull centos

    docker 常用命令：
        环境：
            docker info
            docker version
        系统维护相关：
            images
            inspect 探测容器信息
            build
            commit <id> centos:<tag>  // 创建新的映像
            pause/unpause
            ps -a  // 显示所有的包括已经退出的，ps 不显示退出的
            rm
            rml
            run
            start/stop/restart
            top
            kill
            --rm 退出时自动删除（run运行时指定）
        日志信息相关
            events
            history
            logs
        docker hub服务相关
            login
            loginout
            pull
            push
            search
            push
            
        基本操作：
            获取镜像：pull
            启动容器：run
                -i，-t

        docker 启动之后会默认启动一个虚拟网络

        docker commit <id> centos:newuser
        docker run -it --rm centos:latest /bin/bash

docker 功能
    隔离应用
    维护镜像

 C/S：
    镜像
    容器
    链接
    数据卷

Docker应用
    镜像：包含了启动Docker容器所需要的文件系统层级及其内容，基于UnionFS曹勇分层结构实现

    registry：保存docker镜像及镜像层次结构和元数据
    repository：由具有某个功能的镜像的所有相关版本构成的集合
    index：管理用户的账号，访问权限，镜像及镜像标签
    graph：从registry中下载的docker镜像需要保存在本地，此功能由graph完成
      ls  /var/lib/docker/graph

    与镜像相关的命令
        images
        search
        pull
        push
        login/logout

        创建镜像：commit build
        删除本地镜像：docker image rmi

    容器：
        独立运行的一个或一组应用，以及他们运行的环境，运行中的docker实例

        命令：
            run kill stop start restart 

        启动方法：
            启动镜像创建一个新的容器：run
            启动一个处于停滞状态的容器：start

        run命令：
            --name=  指定一个容器的名字
            -i：是否交互式运行
            -t：是否使用终端，与-i同时使用。
            --net-default：启动这个容器关联的某个桥上
            logs：容器日志，获得其输出信息
            -d：后台运行docker

            ctrl+d  退出  （或者 exit）

        docker run -it --name=busybox busybox:latest /bin/bash
        docker stop busybox 
        docker ps -a
        docker start busybox
        docker attach busybox
        ifconfig
        iptables -nvL
        iptables -t nat -nvL

        步骤：
            检查本地是否存在指定的镜像，不存在则从registry下载
            利用镜像启动容器
            分配一个文件系统，并且在只读的镜像层之外挂载一个可读写层
            从宿主机配置的网桥接口桥接一个虚拟接口给此容器
            从地址池中分配一个地址给容器
            执行用户指定的用户程序
            程序执行完成后容器即终止。

        docker logs <id> // 获取过去所输出的信息
        docker start -i busybox  // 启动应用
        docker help attach // 关联至某个运行容器
        export：导出容器文件到归档文件
        import：归档文件导入为镜像文件
        rm：删除容器
        tag：打标签
        --nat：指定桥

    Docker Hub：
        registry有两种：
            docker hub：注册官方找账号
            private registry：私有仓库

        docker hub：
            docker login
            username：
            password：
            docker help push
            // docker push mageedu/busybox:latest

        private registry：
            开启所有 原 /etc/yum.repos.d/CentOs-Base.repo
            yum list all | grep docker
            yum -y install docker
            yum -y install docker-registry  监听5000 https 服务
            rpm -ql docker-registry
            vim /etc/docker-registry.yml
            vim /etc/sysconfig/docker-registry

            vim /etc/docker-registry
                sqlalchemy_index_database：索引文件存储位置

            systemctl start docker-registry.service
            ss -tnl
                5000
            docker tag <id> ip:5000/busybox:1.2.1
            docker images
            docker push ip:5000/busybox:1.2.1

            解决https改为http
            安装 docker
            ~]# vim /etc/sysconfig/docker
            ADD_REGISTRY='--add-registry 172.16.100.60:5000'
            INSECURE_REGISTRY='--insecure-registry 172.16.100.60:5000'  使用http

            ~]# systemctl restart docker.service
            ~]# docker push 172.16.100.60:5000/busybox:1.2.1
            //  ~]# docker search 172.16.100.60:5000/repositories/busybox
            ~]# docker pull 172.16.100.68:5000/busybox:1.2.1  下拉

            （1）安装docker-registry程序包
            （2）启动服务
                    systemctl start docker-registry.service
            （3）建议nginx反代，使用ssl，基于basic做用户认证

        docker 端使用私有仓库
            (1) 配置文件 /etc/sysconfig/docker
            ADD_REGISTRY 额外添加一个地址
             INSECURE_REGISTRY 使用http而不是https
            (2)push 镜像
                tag命令：要给私有仓库打标签
                docker tag IMAGE_ID REGISRY_HOST:port/name:[tag]
                push 命令
                    docker push host:port/name[tag]

            (3)pull镜像
                docker pull host:port:name[tag]

    Docker 数据卷：
        Data Volume

        数据卷是供一个或多个容器使用的文件或目录，有多种特性
            可以共享于多个容器之间
            对数据卷的修改会立即生效
            对数据卷的更新与镜像无关
            数据卷会一直存在

        使用数据卷的方式
            1：创建时指明数据卷
             -v ：绑定挂载一个卷
                docker help run 
                docker -it --name busybox2 -v /data busybox:latest // 不建议使用
                docker容器修改文件宿主机也会修改，
                默认映射的宿主机目录：/var/lib/docker/volumes/<id>/....
                
                -v /容器/dir 
                -v /宿主机/dir:/容器/dir  
                在dockerfile中使用VOLUME指定

            --volumes-form=容器名 ：只用别的容器卷：容器之间共享卷

            删除容器时同时删除卷
                docker rm -v 容器名
                docker run -rm：容器关闭时自动删除其容器和卷，还有其他容器使用卷则不会删除，必须为最后一个使用的容器

            备份和恢复
                docker run -rm -volumes-form 容器名 -v 目录($(pwd))/backup
                docker run -rm -volumes-form 容器名 -v 目录($(pwd))/backup busybox:latest tar cvf /backup/data.tar /data

        docker 网络
            支持的网络模式：
                1：bridge模式
                --net=BRIDGE_NAME
                    创建一个虚拟网卡，一半在宿主机，一半在容器中

                2：host模式
                    --net=host

                3：container模式

                4：none模式：不使用网络

        ~]# brctl show
        
        容器互联：
            --link=


容器网络模型：
    closed container：封闭式容器
            仅有一个接口：loopback
            不参与网络通信，仅适用于无需网络通讯的场景，备份，程序调试
            ~]# --net none
            ~]# docker run -it -name test --rm --net none busybox:latest /bin/sh

    bridged container：桥接式容器
        loopback
        以太网接口：桥接是docker daemon设定使用的桥。

        --net bridge
        -h , -hostname name
        --dns 
        --add-host "HOSTNAME:IP"  解析地址到域名
        -p 

        ~]# docker run -it --rm --name test busybox:latest /bin/sh

        ~]# docker run -it --rm --name test -h myhost.magedu.com --dnx 172.16.0.1  busybox:latest /bin/sh
        ~]# nslookup docker.com // dns 解析

        docker NAT 桥模型上的容器发布给外部网络访问
            -p <containerPort> 
                仅给出了容器接口，表示将指定的容器端口银蛇至主机上的某随机端口   
            ~]# docker run -it --rm -p 80 --net bridge --name web busybox:latest /bin/sh
            ~]# docker help port 
            ~]# docker port web
            ~]# httpd -f -v  -h  /web/html/      // docker 内部自带httpd
            ~]# iptables -t nat -nvL

            -p <hostPort>::<containerPort>  :将主机端口映射至容器端口
            -p <hostIP>:<HostPort>:<containerPort>  将主机上的hostIP上的端口映射为容器的端口
            -P, --publish-all  发布所有的端口，跟--expose选项一起指明
                ~]# docker run -it --rm -P --expose 80 --expose 8080 --expose 443 --net bidge --name web busybox:lstest /bin/sh
                ~]# docker inspect web  // 查看镜像与容器信息
                // ~]# docker inspect -f ExposedPorts web 
                
        如果启动时不适用docker:0 桥接口，运行时指明 -b 选项：指明要使用的桥

        联盟式容器：两个容器使用同一个名称空间
            启动一个容器时，让其使用某个已经存在的容器的网络名称空间
            ~]# docker run --rm --name joined_web --net 
            --net container:CONTAINER_NAME
            ~]# docker run --rm --name joined_web --net container:web busybox:latest ifconfig -a 
            ~]# docker run --rm --name joined_web --net container:web busybox:latest netstat -tan

        开放时容器：
            容器使用Host的网络名称空间
                --net Host 
                ~]# docker run -it --rm --net host --name web  busybox:latest /bin/sh

                ~]# docker run -it --rm --net host --name web  centos:latest /bin/bash
                ~]# yum install iproute

        程序一定要运行于前台。
            -d ：将docker运行于守护进程
                ~]# docker run --name web --net bridge busybox:latest httpd
                ~]# docker run --name web --net bridge busybox:latest httpd -f  // 前台运行
                ~]# docker run -d --name web --net bridge -p 80:80 busybox:latest httpd -f


        容器间的依赖关系：
            链接机制：linking
                link

            容器集群
                docker官网：swarm machine compose
                apache基金会：mesos marascon
                google：kubemetes

            docker书：
                Docker in Action
                Using Docker
                Docker cookbook

        docker 监控命令：
            ps -a
            images
            stats：容器状态信息统计,实时监控
            --shm-size
            --cpuset-cpu
            inspect：查看镜像或容器底层信息，json格式
                -f 查看某一个键内容
                ~]# docker inspect -f {{.state.Pid}} web
            top：查看容器进程运行状态
            port：

            ~]# /google/cadvisor-canary   查看容器信息

-------------------------------------
Dockerfile：
    
    Docker images：
        docker commit
        dockerfile：文本文件，镜像文件构建脚本

    Dockerfile：根据基础镜像构建新的镜像文件的专用指令序列组成
        指令：选定基础镜像，安装必要的程序，复制配置文件和数据文件，自动运行的服务，外部端口

        命令：docker build

        语法：指令行，注释行和空白行
            指令行：字符不区分大小写，约定全部使用大写字符
            注释行：# 开头

        指令：
            FORM ：必须是第一个非注释行，用于指定所用到的基础镜像，来构建
                语法格式：
                    FORM <image>[tag]
                    FORM <image>@<digest>

                    ~]# FORM busybox:latest
                    ~]# FORM centos:6.9

                注意：可以使用多个FORM，但是尽量不要使用多个FORM指令

            MAINTANIER：用于提供信息的指令，让作者提供本人信息，不限制出现位置，建议紧跟FORM之后
                语法格式：
                    MAINTANIER <authors detail>

            COPY：用于从docker主机（宿主机）复制文件至正在创建的映像文件中
                语法格式：
                    COPY <src> .... <dest>
                    COPY ["<src>",  ... "<dest>"] // 文件名有空白字符 逗号隔开

                    注意：dest 建议使用绝对路径
                             新复制生成的目录文件的uid和sid均为0  （属主属组为0）
                             src 必须是build上下文的路径，不能使用 ../ 目录
                             src 是目录，会自动递归复制，使用src 通配符时是多个使用通配符时，dest 必须是目录，必须以 / 结尾 
                             dest 事先不存在，自动创建，包括其父目录

             ADD：类似于copy 命令，额外还支持 TAR 文件，以及URL路径，使用格式同COPY
                ADD http;//... <dest>
                    注意：以URL格式指定的源文件，下载完成后其目标文件权限为 600 
                                本地tar格式复制后直接解压，而url下载后不会直接解压

             ENV：环境变量
                此变量可以被当前dockerfile文件直接调用，调用格式为 $variable_name 或者 $(variable_name)
                语法格式：
                    ENV <key> <value>    只能定义一个
                    ENV <key>=<value> ....  可以定义多个，value中不能有空格，如果有空白字符进行转义或加引号
                    换行  <tab>|<space>  

                    注意：镜像运行后环境变量一直存在，。使用 inspect 查看，启动时 --env 修改变量的值

            USER：指定用户身份，dockerfile 文件的任何运行 RUN/CMD/ENTARPOINT 指令指定程序的用户名或uid
                注意：uid必须存在

            WORKDIR：用于为dockerfile总所有的 RUN/CMD/ENTRYPOINT/COPY/ADD 指定工作目录
                语法格式
                    WORKDIR <dirpath>

                    注意：WORKDIR可以出现多次，亦可以使用相对路径，相对于前一个WORKDIR指定的路径，WORKDIR还可以调用ENV的值

            VOLUME：为镜像文件中创建一个挂载点目录，用户挂载主机上的卷，或其它容器的卷
                语法格式：
                    VOLUME <mountpoint>
                    VOLUME ["<mountpoint>", ....]  逗号隔开

                注意：如果mountpoint 路径事先存在文件，将此前的卷复制进来，叠加


            RUN：指定docker build过程中要运行的命令。而不是docker run此dockerfile构建成的镜像运行
                语法格式：
                    RUN <command>  // 一个shell 命令,不能接收pid信号
                    RUN ["<executable>", "<param1>", "<param2>", ....] // 一个命令多个参数，不是在shell中运行。而是一个解释器

                    ~]# RUN yum install iproute nginx && yum clean alls

                注意：建议放在同一个run中

            CMD：类似于RUN，用于运行程序，docker run 时运行，而非 docker build
                CMD指令的首要目的在于为启动的容器指定默认运行的程序，程序运行结束，容器也就结束，不过CMD指令指定的程序可被docker run 命令行参数中指定要运行的程序锁覆盖
                语法格式：
                    CMD <command>
                    CMD ["<executable>", "<param1>", "<param2>", ..]
                    CMD ["<param1>", "param2>", ..]

                注意：存在多个CMD指令，仅最后一个生效

            ENTRYPOINT：类似于cmd指令，但其不会被docker run 命令行参数指定的命令所覆盖，这些命令行参数会被当做参数送给 ENTRYPOINT 指定的程序，但是运行docker run时使用了 --entrypoint ，此选项可当做要运行的程序覆盖 ENTRYPOINT 指定的程序

                语法格式：
                    ENTRYPOINT <command>
                    ENTRYPOINT ["<executable>", "<param1>", "<param2>", ..]

                例如：
                    CMD ['-C']
                    ENTRYPOINT ['top', '-b']

            EXPOSE：用于为容器指定要暴露的端口
                语法格式：
                    EXPOSE <port>[/<protocol>] [<port>[/<protocol>]] .....
                        <protocal>为tcp或udp二者之一，默认为tcp

            ONBUILD：定义触发器
                当前dockerfile构建出的镜像被用作基础镜像去构建其他镜像时，该指令的操作才会被执行
                语法格式：
                    ONBUILD <INSTRUCTION>
                    例如：
                        ONBUILD ADD my.cnf  /etc/mysql/my.cnf

                    注意：ONBUILD不能自我嵌套，且不会触发 FROM 和 MAINTAINER 指令

=============================
/root/docker/test.dockerfile
==============================
# Magedu
FORM busybox:latest
MAINTAINER magedu <magedu@magedu.com>

COPY index.html /web/html/index.html

CMD ["httpd", "-f", "-h", "/web/html/"]


===============================
执行构建：
 docker build -f /root/docker/test.dockerfile /root/docker/
 docker build -f /root/docker/test.dockerfile -t busybox:webserver /root/docker/

docker run -d --rm busybox:web2
docker port <id>
docker run -d --name web -P busybox:web2


---------------------------------------------
容器的导入和导出
    docker export
    docker import
镜像的保存及装载
    docker save -o /PATH/ NAME[:TAG]
    docker load -i /PATH/..

-------------------------------------------------------------
FROM centos:latest
MAINTAINER magedu
RUN sed -i -e 's@^mirrorlist.*repo=os.*$@baseurl='
RUN yum -y install httpd php php-mysql php-mbstring && yum clean all 















